package com.ds.esd.admin.plugins.service;

import com.ds.common.JDSException;
import com.ds.common.md5.MD5;
import com.ds.common.util.IOUtility;
import com.ds.common.util.StringUtility;
import com.ds.config.ErrorListResultModel;
import com.ds.config.JDSConfig;
import com.ds.config.ListResultModel;
import com.ds.config.ResultModel;
import com.ds.context.JDSActionContext;
import com.ds.enums.db.MethodChinaName;
import com.ds.esd.admin.node.XUIFile;
import com.ds.esd.client.ESDClient;
import com.ds.esd.client.ESDFacrory;
import com.ds.esd.client.ProjectVersion;
import com.ds.esd.editor.enums.PackagePathType;
import com.ds.esd.editor.enums.PackageType;
import com.ds.esd.plugins.font.node.FontConfig;
import com.ds.esd.project.enums.ProjectDefAccess;
import com.ds.esd.tool.module.EUModule;
import com.ds.vfs.FileInfo;
import com.ds.vfs.Folder;
import com.ds.vfs.VFSConstants;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

@Controller
@RequestMapping(value = {"/RAD/{projectName}/"})
@MethodChinaName(cname = "XUI编辑器")
public class RADEditor {

    @RequestMapping(value = {"export"}, method = {RequestMethod.GET})
    @ResponseBody
    public ResultModel<Boolean> export(@PathVariable String projectName) {
        ResultModel<Boolean> resultModel = new ResultModel<Boolean>();
        try {
            ProjectVersion version = getClient().getProjectVersionByName(projectName);
            List<FileInfo> fileInfos = version.getRootFolder().getFileListRecursively();
            for (FileInfo fileInfo : fileInfos) {
                if (!fileInfo.getName().endsWith(".cls")) {
                    String localPath = JDSConfig.Config.tempPath().getPath() + File.separator;
                    String realPath = StringUtility.replace(fileInfo.getPath(), version.getRootFolder().getPath(), "/");
                    File file = new File(localPath + realPath);
                    InputStream input = fileInfo.getCurrentVersion().getInputStream();
                    if (file.getParentFile() != null && !file.getParentFile().exists()) {
                        file.getParentFile().mkdirs();
                    }

                    if (!file.exists()) {
                        file.createNewFile();
                    }
                    FileOutputStream output = new FileOutputStream(file);
                    IOUtility.copy(input, output);
                    IOUtility.shutdownStream(input);
                    IOUtility.shutdownStream(output);
                }

            }
            JDSActionContext.getActionContext().getContext().put("build", "false");
            Set<EUModule> modules = version.getAllModule();
            for (EUModule module : modules) {
                String localPath = JDSConfig.Config.tempPath().getPath() + File.separator;
                File file = new File(localPath + "cls/" + MD5.getHashString(module.getClassName()));
                StringBuffer json = ESDFacrory.getESDClient().genJSON(module, null);
                InputStream input = null;

                input = new ByteArrayInputStream(json.toString().getBytes(VFSConstants.Default_Encoding));
                if (file.getParentFile() != null && !file.getParentFile().exists()) {
                    file.getParentFile().mkdirs();
                }

                if (!file.exists()) {
                    file.createNewFile();
                }
                FileOutputStream output = new FileOutputStream(file);
                IOUtility.copy(input, output);
                IOUtility.shutdownStream(input);
                IOUtility.shutdownStream(output);
            }
            JDSActionContext.getActionContext().getContext().remove("build");

        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (JDSException e) {
            e.printStackTrace();
        }
        //本地备份文件
        return resultModel;
    }

    @RequestMapping(value = {"debug"}, method = {RequestMethod.GET})
    public ModelAndView debug(ModelAndView mv, @PathVariable String projectName) {
        mv.addObject("projectName", projectName);
        List<FileInfo> cssFiles = new ArrayList<FileInfo>();
        try {
            ProjectVersion version = getClient().getProjectVersionByName(projectName);
            List<FontConfig> fontNodes = version.getProject().getFonts();
            for (FontConfig fontNode : fontNodes) {
                Folder folder = getClient().getFolderByPath(fontNode.getFile());
                List<FileInfo> fileInfos = folder.getFileListRecursively();
                for (FileInfo cssFile : fileInfos) {
                    if (cssFile.getName().endsWith(".css")) {
                        if (!cssFiles.contains(cssFile)) {
                            cssFiles.add(cssFile);
                        }

                    }
                }
            }
        } catch (JDSException e) {
            e.printStackTrace();
        }
        mv.addObject("cssFiles", cssFiles);
        mv.setViewName("/projectDebug");
        return mv;
    }

    private List<XUIFile> getTopFolder(String projectName, PackageType type) throws JDSException {
        List<XUIFile> modules = new ArrayList<XUIFile>();
        ProjectVersion projectVersion = getClient().getProjectVersionByName(projectName);
        List<Folder> folders = projectVersion.getRootFolder().getChildrenList();
        for (Folder cfolder : folders) {
            String path = StringUtility.replace(cfolder.getPath(), projectVersion.getPath(), "/");
            PackagePathType packagePathType = PackagePathType.startPath(path);
            if (packagePathType == null || type == null || packagePathType.getApiType().equals(type) || projectVersion.getProject().getProjectType().equals(ProjectDefAccess.DSM)) {
                modules.add(new XUIFile(cfolder, projectVersion));
            }
        }

        return modules;
    }


    @MethodChinaName(cname = "装载系统目录")
    @RequestMapping(value = {"loadSystemFolder"}, method = {RequestMethod.GET})
    public @ResponseBody
    ListResultModel<List<XUIFile>> loadSystemFolder(@PathVariable String projectName) {
        ListResultModel<List<XUIFile>> result = new ListResultModel<List<XUIFile>>();
        try {
            List<XUIFile> modules = new ArrayList<XUIFile>();
            getClient().reLoadProjectRoot(projectName);
            modules = getTopFolder(projectName, PackageType.system);
            result.setData(modules);
        } catch (JDSException e) {
            result = new ErrorListResultModel<>();
            ((ErrorListResultModel) result).setErrcode(JDSException.APPLICATIONNOTFOUNDERROR);
            ((ErrorListResultModel) result).setErrdes(e.getMessage());

        }

        return result;
    }


    @MethodChinaName(cname = "装载工程")
    @RequestMapping(value = {"openProject"}, method = {RequestMethod.GET})
    public @ResponseBody
    ListResultModel<List<XUIFile>> openProject(@PathVariable String projectName) {
        ListResultModel<List<XUIFile>> result = new ListResultModel<List<XUIFile>>();
        List<XUIFile> modules = new ArrayList<XUIFile>();
        String[] systemFiles = new String[]{"ProjectConfig.cfg", "xuiconf.js"};
        try {
            ProjectVersion projectVersion = getClient().getProjectVersionByName(projectName);
            // getClient().reLoadProjectRoot(projectName);
            modules = getTopFolder(projectName, PackageType.local);
            List<FileInfo> infos = projectVersion.getRootFolder().getFileList();
            for (FileInfo fileInfo : infos) {
                boolean isSystem = false;
                for (String name : systemFiles) {
                    if (fileInfo.getName().equals(name)) {
                        isSystem = true;
                    }
                }
                if (!isSystem) {
                    if (!fileInfo.getName().endsWith(".cls")) {
                        modules.add(new XUIFile(fileInfo, projectVersion));
                    } else {
                        EUModule module = projectVersion.getModule(fileInfo.getPath());
                        modules.add(new XUIFile(module));
                    }
                }
            }
            result.setData(modules);
        } catch (JDSException e) {
            result = new ErrorListResultModel<>();
            ((ErrorListResultModel) result).setErrcode(JDSException.APPLICATIONNOTFOUNDERROR);
            ((ErrorListResultModel) result).setErrdes(e.getMessage());

        }

        return result;
    }


    @MethodChinaName(cname = "获取工程配置信息")
    @RequestMapping(value = {"getProjectConfig"}, produces = "application/javascript;charset=utf-8", method = {RequestMethod.GET, RequestMethod.POST})
    public @ResponseBody
    String getProjectConfig(@PathVariable String projectName) {
        String conf = "{}";
        try {
            conf = this.getClient().readFileAsString("xuiconf.js", projectName);
        } catch (JDSException e) {
            e.printStackTrace();
            return e.getMessage();
        }
        return conf;
    }


    ESDClient getClient() throws JDSException {
        ESDClient client = ESDFacrory.getESDClient();
        return client;
    }

}
